package com.authine.cloudpivot.ext.controller.notify;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.enums.ZzdEventTag;
import com.authine.cloudpivot.ext.service.IZzdEventCallbackService;
import com.authine.cloudpivot.ext.service.SyncOrgSevice;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.view.ResponseResult;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 专有钉消息回调接收接口
 * 
 * @author shinka
 * @date 2021/07/13
 * @version 1.0
 */
@Api(value = "EXTAPI::专有钉消息回调接收接口", tags = "01::EXTAPI::专有钉消息回调接收接口")
@RestController
@RequestMapping("/public/ext/notify")
public class ZzdEventCallbackController extends BaseController {

    private static Logger log = LoggerFactory.getLogger(ZzdEventCallbackController.class);

    @Resource
    private SyncOrgSevice syncOrgSevice;

    @Autowired
    private IZzdEventCallbackService zzdEventCallbackService;

    @Value("${syncorg.notify.callbackUrl}")
    private String notifyCallbackUrl;

    @Value("${syncorg.notify.enable:false}")
    private boolean notifyEnable;

    /**
     * 功能描述: 注册消息回调
     * 
     * @author TED 2021年6月23日
     * @author shinka
     * @version 2.0
     */
    @ApiOperation(value = "注册消息回调")
    @GetMapping(value = "/register_event_callback")
    public ResponseResult<Map<String, Object>> registerEventCallback() {
        JSONObject result = new JSONObject();
        for (ZzdEventTag tag : ZzdEventTag.values()) {
            String eventName = tag.getName();
            String eventTag = tag.getValue();
            Map<String, Object> resultMap = syncOrgSevice.registerEventCallback(eventTag, notifyCallbackUrl);
            result.put(eventName + "：" + eventTag, resultMap);
        }
        return getOkResponseResult(result, "注册消息回调完成");
    }

    /**
     * 功能描述: 查询定义的事件列表
     * 
     * @author TED
     * @date 2021年6月23日
     * @version: 1.0
     */
    @ApiOperation(value = "查询定义的事件列表")
    @GetMapping(value = "/query_callback_define")
    public ResponseResult<Map<String, Object>> queryCallbackDefine() {
        Map<String, Object> result = syncOrgSevice.queryCallbackDefine();
        return getOkResponseResult(result, "query_callback_define运行成功!");
    }

    /**
     * 功能描述: 更新事件回调的定义信息
     * 
     * @author TED
     * @date 2021年6月23日
     * @version: 1.0
     */
    @ApiOperation(value = "更新事件回调的定义信息")
    @GetMapping(value = "/update_event_callback_define")
    public ResponseResult<Map<String, Object>> updateEventCallbackDefine(Long eventCallbackId, String callbackUrl) {
        if (StringUtils.isEmpty(callbackUrl)) {
            callbackUrl = notifyCallbackUrl;
        }
        Map<String, Object> result = syncOrgSevice.updateEventCallbackDefine(eventCallbackId, callbackUrl);
        return getOkResponseResult(result, "update_event_callback_define运行成功!");
    }

    /**
     * 功能描述: 删除事件回调的定义信息
     * 
     * @author TED
     * @date 2021年6月23日
     * @version: 1.0
     */
    @ApiOperation(value = "删除事件回调的定义信息")
    @GetMapping(value = "/delete_event_callback_define")
    public ResponseResult<Map<String, Object>> deleteEventCallbackDefine(Long eventCallbackId) {
        Map<String, Object> result = syncOrgSevice.deleteEventCallbackDefine(eventCallbackId);
        return getOkResponseResult(result, "delete_event_callback_define运行成功!");
    }

    /**
     * 功能描述: 查询回调失败信息
     * 
     * @author TED
     * @date 2021年6月23日
     * @version: 1.0
     */
    @ApiOperation(value = "查询回调失败信息")
    @GetMapping(value = "query_callback_failed")
    public ResponseResult<Map<String, Object>> queryCallbackFailed() {
        Map<String, Object> result = syncOrgSevice.queryCallbackFailed();
        return getOkResponseResult(result, "query_callback_failede运行成功!");
    }

    /**
     * 功能描述: 重试失败回调
     * 
     * @author TED
     * @date 2021年6月23日
     * @version: 1.0
     */
    @ApiOperation(value = "重试失败回调")
    @GetMapping(value = "retry_callback_failed")
    public ResponseResult<Map<String, Object>> retryCallbackFailed(Long eventCallbackFailedId) {
        Map<String, Object> result = syncOrgSevice.retryCallbackFailed(eventCallbackFailedId);
        return getOkResponseResult(result, "retry_callback_failed运行成功!");
    }

    /**
     * 功能描述: 移除失败回调
     * 
     * @author TED
     * @date 2021年6月23日
     * @version: 1.0
     */
    @ApiOperation(value = "移除失败回调")
    @GetMapping(value = "remove_callback_failed")
    public ResponseResult<Map<String, Object>> removeCallbackFailed(Long eventCallbackFailedId) {
        Map<String, Object> result = syncOrgSevice.removeCallbackFailed(eventCallbackFailedId);
        return getOkResponseResult(result, "remove_callback_failed运行成功!");
    }

    /**
     * 专有钉消息回调接收
     * 
     * @see com.authine.cloudpivot.ext.controller.notify.ZzdEventCallbackController
     * @param body
     *            （一） 请求register_event_callback接口时，消息网关会向callbackUrl发送校验联通性消息，回调接口必须为POST，消息body体如下：<br/>
     *            -- "eventTag":"MOZI_VDS_TENANT_CHANGE|ORGANIZATION_ADD_UPDATE",<br/>
     *            -- "dispatchId":"0e276c97-c3f9-44c2-88ab-335123991c45" <br/>
     *            （二）注册成功后，消息网关会向callbackUrl发送消息，消息示例： <br/>
     *            header: <br/>
     *            -- _TENANT_ID_:标记租户id <br/>
     *            -- _EVENT_NAME_:事件名 <br/>
     *            -- _DISPATCH_ID_:分发id <br/>
     *            -- _SOURCE_MESSAGE_ID_:源消息的id <br/>
     *            -- _CALLBACK_MESSAGE_ID_:网关的mq的id <br/>
     *            body（form表单格式）: <br/>
     *            -- tenantId=租户ID <br/>
     *            -- &eventName=事件名 <br/>
     *            -- &eventTag=事件名（兼容老版本 <br/>
     *            -- &dispatchId=消息分发id <br/>
     *            -- &sourceMessageId=原消息id,订阅方请忽略 <br/>
     *            -- &callbackMessageId=转发后的消息id,订阅方请忽略 <br/>
     *            -- &content=业务方传过来的字段
     * @return 注册方必须返回：{"errcode":"0","errmsg":"成功"}
     */
    @ApiOperation(value = "专有钉注册消息回调接收")
    @PostMapping(value = "/callback")
    public Map<String, Object> callback(HttpServletRequest request) {
        // 固定返回如下内容，代表消息接收成功
        Map<String, Object> result = new HashMap<>();
        result.put("errcode", "0");
        result.put("errmsg", "成功");

        try {
            String dispatchId = request.getParameter("dispatchId");
            String eventTag = request.getParameter("eventTag");
            String content = request.getParameter("content");

            log.debug("专有钉回调接收，钉钉消息体：{eventTag:{},dispatchId:{},content:{}}", eventTag, dispatchId, content);

            if (!notifyEnable) {
                log.debug("是否处理推送事件，notifyEnable={}", notifyEnable);
                return result;
            }
            if (StringUtils.isEmpty(content)) {
                // 注册消息回调，不处理业务逻辑
                log.debug("事件注册验证，content={}", content);
                return result;
            }

            JSONObject contentJson = JSONObject.parseObject(content);
            // 增加/更新组织
            if (ZzdEventTag.ORG_addOrUpdateOrg.getValue().equals(eventTag)) {
                zzdEventCallbackService.addOrUpdateOrg(contentJson);
            }
            // 组织变更父组织
            else if (ZzdEventTag.ORG_modifyParentOrg.getValue().equals(eventTag)) {
                zzdEventCallbackService.modifyParentOrg(contentJson);
            }
            // 删除组织
            else if (ZzdEventTag.ORG_deleteOrg.getValue().equals(eventTag)) {
                zzdEventCallbackService.deleteOrg(contentJson);
            }
            // 增加/更新员工
            else if (ZzdEventTag.USER_addOrUpdateUser.getValue().equals(eventTag)) {
                zzdEventCallbackService.addOrUpdateUser(contentJson);
            }
            // 删除员工
            else if (ZzdEventTag.USER_deleteUser.getValue().equals(eventTag)) {
                zzdEventCallbackService.deleteUser(contentJson);
            }
            // 组织关联员工
            else if (ZzdEventTag.USER_orgRelatedUser.getValue().equals(eventTag)) {
                log.debug("组织关联员工：暂不匹配该事件类型，eventTag={}", eventTag);
            }
            // 组织取关员工
            else if (ZzdEventTag.USER_orgCancelRelatedUser.getValue().equals(eventTag)) {
                // 删除实际上走取关
                zzdEventCallbackService.orgCancelRelatedUser(contentJson);
            } else {
                log.debug("专有钉回调接收，回调eventTag不匹配，eventTag={}", eventTag);
            }
        } catch (Exception e) {
            log.error("专有钉回调，业务逻辑处理失败，exception={}", e);
        }
        return result;
    }

}
